import MysqlCore from "../core/MysqlCore";
import Expression from "./interface/Expression";
import CoreExpression from "./abstract/CoreExpression";
import UnchangedExpression from "./impl/UnchangedExpression";

/** 查询条件对象 */
declare type SqlType =
    typeof MetaData.SELECT
    | typeof MetaData.UPDATE
    | typeof MetaData.DELETE
    | typeof MetaData.INSERT;

class MetaData {
    /**
     * 格式化程序
     */
    public static FIELDFORMAT: { [key: string]: (name: string) => string } = {
        /**
         * 大驼峰格式化
         */
        bigHump(field: string) {
            return field[0].toUpperCase() + field.substring(1).replace(/(?<=_)./g, e => e.toUpperCase());
        },
        /**
         * 小驼峰格式化
         */
        smallHump(field: string) {
            return field[0].toLowerCase() + field.substring(1).replace(/(?<=_)./g, e => e.toUpperCase());
        },
        /**
         * 下划线格式化
         */
        underline(field: string) {
            return field[0].toLowerCase() + field.substring(1).replace(/[A-Z]/g, e => "_" + e.toLowerCase());
        }
    }
    public static SELECT: "select" = "select";
    public static UPDATE: "update" = "update";
    public static DELETE: "delete" = "delete";
    public static INSERT: "insert" = "insert";
    /** 数据库字段规范 */
    public sqlFieldRule: string;
    /** 程序变量名规范 */
    public codeFieldRule: string;
    /** 执行的类型 */
    public type: SqlType = MetaData.SELECT;
    /** 作用域中的表名 */
    public table: Expression;
    /** 查询字段 */
    public fields: string = "*";
    /** sql实例对象 */
    public expressionList: Array<Expression> = [];
    /** 参与预编译的参数 */
    public parameter: any[] = [];
    public core: MysqlCore;
    /** 是否执行了where */
    public isWhere: boolean = false;
    /** 是否执行了on */
    public isOn: boolean = false;
    /** 是否是子查询 */
    public isSubquery: boolean = false;
    /** 是否完成表达式 */
    public status:boolean = false;

    /** 生命周期 */
    lifeCycle?: {
        /** 执行前 */
        before: (option: any) => {};
        /** 执行后 */
        after: (data: any) => {};
    };

    constructor(core: MysqlCore | MetaData, sqlFieldRule?: string, codeFieldRule?: string, table: Expression = {} as Expression) {
        if (core instanceof MetaData) {
            this.core = core.core;
            this.sqlFieldRule = core.sqlFieldRule;
            this.codeFieldRule = core.codeFieldRule;
            this.table = table;
        } else {
            this.core = core;
            this.sqlFieldRule = sqlFieldRule as string;
            this.codeFieldRule = codeFieldRule as string;
            this.table = table;
        }
    }

    public add(ex: Expression, position?: number) {
        if (position !== undefined) {
            this.expressionList.splice(position, 0, ex);
        } else {
            this.expressionList.push(ex);
        }
        return ex;
    }


    public toSql(completion: boolean = false) {
        return this.expressionList[0].toSql(completion);
    }

    public handlSqlField(name: string) {
        return MetaData.FIELDFORMAT[this.sqlFieldRule](name);
    }

    public handlCodeField(name: string) {
        return MetaData.FIELDFORMAT[this.codeFieldRule](name);
    }

    /** 完成表达式 */
    public complete(){
        if(this.status){
            return this;
        }
        // 判断是否进行了表查询,有表查询才能完结
        if(this.expressionList.some(e=>e.type === 'table')){
            CoreExpression.prototype.get.bind({metadata:this})()
        }
        return this;
    }
    /** 封装 */
    public seal(position:number=0){
        this.add(new UnchangedExpression("(",this),position);
        this.add(new UnchangedExpression(")",this));
    }
}

export = MetaData;